﻿using System;
using System.Data.SqlClient;
using sscore;
using System.IO;

namespace DM4
{
    public partial class DM4
    {
        public XMLInfo GetGroupList(string usrSessionId, bool showall = false)
        {
            BeginFunction("GetGroupList");

            OperationResult userIdOpResult = GetUserIdBySession(usrSessionId);
            XMLInfo xi = new XMLInfo(userIdOpResult);

            if (!userIdOpResult)
            {
                WriteLog(userIdOpResult.Message, MessageType.Error);
                return xi;
            }

            int userId = userIdOpResult.Result;
            WriteLog(String.Format("Get group info list for user id [{0}]", userId));

            string sql = "select * from groups left outer join users on grp_usr = usr_id left outer join scripts on grp_script = scr_id ";

            UserInfo ui = GetUserInfo(userId);

            string where = "WHERE usr_id IS NULL";
            if (String.IsNullOrEmpty(ui.UsrLogin))
                where = "WHERE usr_id = -100"; //unknown user
            else
            {
                if ((ui.UsrAccessLevel != AccessLevel.Admin) || ((ui.UsrAccessLevel == AccessLevel.Admin) && (!showall)))
                    where += String.Format(" or usr_id = '{0}'", userId);

                if ((ui.UsrAccessLevel == AccessLevel.Admin) && (showall))
                    where = "";
            }

            sql += where;
            WriteDebugLog(sql);

            try
            {
                SqlCommand sel = new SqlCommand(sql, _conn);
                using (SqlDataReader reader = sel.ExecuteReader())
                {
                    if (reader.HasRows)
                        try
                        {
                            WriteLog(String.Format("Get group info list for user id [{0}] operation complete", userId));
                            xi.Load(reader, "groups");
                        }

                        catch (Exception ex)
                        {
                            WriteLog(ex.Message, MessageType.Error);
                        }
                }
            }

            catch (Exception ex)
            {
                WriteLog(ex.Message, MessageType.Error);
            }

            EndFunction("GetGroupList");
            return xi;
        }

        public OperationResult AddGroup(string usrSessionId, bool publicGroup, string name, string description, string homedir, int scriptId)
        {
            //input :   script_id < 0 = null
            //          usrSessionId < 0 = null
            //result:
            //>0   group id            

            BeginFunction("AddGroup");

            OperationResult userIdOpResult = GetUserIdBySession(usrSessionId);
            if (!userIdOpResult) return userIdOpResult;

            int userId = userIdOpResult.Result;
            OperationResult result = new OperationResult(userIdOpResult, DM4Consts.ErrorUnknown);

            WriteLog("Attemtp to add group...");
            try
            {
                GroupInfo gi = GetGroupInfo(name);

                if (String.IsNullOrEmpty(gi.GrpName))
                {
                    //insert group
                    string homedirex = String.Format("{0}\\{1}", _prm.GetStringParam("WorkDir"), name);

                    string usrid = publicGroup ? DM4Consts.SNULL : String.Format("'{0}'", userId.ToString());
                    string scrId = scriptId < 0 ? DM4Consts.SNULL : String.Format("'{0}'", scriptId.ToString());

                    string sql = String.Format("insert  into groups (grp_name, grp_description, grp_homedir, grp_script, grp_usr) " +
                                        " values ('{0}', '{1}', '{2}', {3}, {4})",
                                        name, description, homedirex, scrId, usrid);

                    WriteDebugLog(sql);
                    SqlCommand sc = new SqlCommand(sql, _conn);
                    sc.ExecuteNonQuery();

                    if (!Directory.Exists(homedirex))
                        Directory.CreateDirectory(homedirex);

                    gi = GetGroupInfo(name);
                    result.Result = gi.GrpId;
                    result.Message = String.Format("Group with name [{0}] added", name);
                    WriteLog(result.Message);
                }
                else
                {
                    result.Result = DM4Consts.ErrorEntityWithSomeNameAlreadyExists;
                    result.Message = String.Format("Group with name [{0}] already exists", name);
                    WriteLog(result.Message, MessageType.Error);
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message, MessageType.Error);
            }

            EndFunction("AddGroup");

            return result;
        }

        public OperationResult EditGroup(string usrSessionId, int grpId, string name, string description, string homedir, int scriptId)
        {
            //input : script_id < 0 = null  

            //result:
            //>0 group id            
            BeginFunction("EditGroup");

            OperationResult userIdOpResult = GetUserIdBySession(usrSessionId);
            if (!userIdOpResult) return userIdOpResult;

            int userId = userIdOpResult.Result;
            OperationResult result = new OperationResult(userIdOpResult, DM4Consts.ErrorUnknown);

            WriteLog(String.Format("Attemtp to edit group [{0}]...", grpId));
            try
            {
                GroupInfo gi = GetGroupInfo(grpId);

                if (!String.IsNullOrEmpty(gi.GrpName))
                {
                    UserInfo ui = GetUserInfo(userId);
                    if (String.IsNullOrEmpty(ui.UsrLogin))
                    {
                        result.Result = DM4Consts.ErrorUnknownUser;
                        result.Message = String.Format("Unknown user with id [{0}]", userId);
                        WriteLog(result.Message, MessageType.Error);
                    }
                    else
                    {
                        //check access
                        bool editEnabled = (gi.GrpUsr == ui.UsrId);
                        editEnabled = editEnabled || (ui.UsrAccessLevel == AccessLevel.Admin);
                        editEnabled = editEnabled && (grpId != DM4Consts.DefaultModulesGroupId);

                        if (editEnabled)
                        {
                            //delete sessions

                            //delete modules

                            //update group
                            WriteDebugLog(String.Format("Script id = {0}", scriptId.ToString()));
                            string scrId = scriptId < 0 ? DM4Consts.SNULL : String.Format("'{0}'", scriptId.ToString());
                            string homedirex = String.Format("{0}\\{1}", _prm.GetStringParam("WorkDir"), name);

                            string sql = String.Format("update groups set grp_name='{0}', grp_description = '{1}', grp_homedir = '{2}', grp_script = {3} where grp_id = {4} ",
                                                               name, description, homedirex, scrId, grpId);

                            WriteDebugLog(sql);
                            SqlCommand sc = new SqlCommand(sql, _conn);
                            sc.ExecuteNonQuery();

                            //scan and add modules

                            gi = GetGroupInfo(name);
                            result.Result = gi.GrpId;
                            result.Message = String.Format("Group with id [{0}] modified", grpId);
                            WriteLog(result.Message);
                        }
                        else
                        {
                            result.Result = DM4Consts.ErrorAccessDenied;
                            result.Message = String.Format("Access denied for user [{0}] to edit group [{1}]", userId, grpId);
                            WriteLog(result.Message, MessageType.Error);
                        }
                    }
                }
                else
                {
                    result.Result = DM4Consts.ErrorUnknownEntity;
                    result.Message = String.Format("Unknown group with id [{0}]", grpId);
                    WriteLog(result.Message, MessageType.Error);
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message, MessageType.Error);
            }

            EndFunction("EditGroup");

            return result;
        }

        public OperationResult DeleteGroup(string usrSessionId, int grpId)
        {
            //result:
            //0  Ok

            BeginFunction("DeleteGroup");

            OperationResult userIdOpResult = GetUserIdBySession(usrSessionId);
            if (!userIdOpResult) return userIdOpResult;

            int userId = userIdOpResult.Result;
            OperationResult result = new OperationResult(userIdOpResult, DM4Consts.ErrorUnknown);

            WriteLog(String.Format("Attemtp to delete group [{0}]...", grpId));
            try
            {
                GroupInfo gi = GetGroupInfo(grpId);

                if (!String.IsNullOrEmpty(gi.GrpName))
                {
                    UserInfo ui = GetUserInfo(userId);
                    if (String.IsNullOrEmpty(ui.UsrLogin))
                    {
                        result.Result = DM4Consts.ErrorUnknownUser;
                        result.Message = String.Format("Unknown user with id [{0}]", userId);
                        WriteLog(result.Message, MessageType.Error);
                    }
                    else
                    {
                        //check access
                        bool editEnabled = (gi.GrpUsr == ui.UsrId);
                        editEnabled = editEnabled || (ui.UsrAccessLevel == AccessLevel.Admin);
                        editEnabled = editEnabled && (grpId != DM4Consts.DefaultModulesGroupId);

                        if (editEnabled)
                        {
                            //delete sessions

                            //delete modules

                            //delete group
                            string sql = String.Format("delete from groups where grp_id = {0}", grpId);

                            WriteDebugLog(sql);
                            SqlCommand sc = new SqlCommand(sql, _conn);
                            sc.ExecuteNonQuery();

                            result.Result = DM4Consts.Ok;
                            result.Message = String.Format("Group with id [{0}] deleted", grpId);
                            WriteLog(result.Message);
                        }
                        else
                        {
                            result.Result = DM4Consts.ErrorAccessDenied;
                            result.Message = String.Format("Access denied for user [{0}] to edit group [{1}]", userId, grpId);
                            WriteLog(result.Message, MessageType.Error);
                        }
                    }
                }
                else
                {
                    result.Result = DM4Consts.ErrorUnknownEntity;
                    result.Message = String.Format("Unknown group with id [{0}]", grpId);
                    WriteLog(result.Message, MessageType.Error);
                }
            }

            catch (Exception ex)
            {
                WriteLog(ex.Message, MessageType.Error);
            }

            EndFunction("DeleteGroup");

            return result;
        }
    }
}
